import React, { Component } from 'react';
import Paper from 'material-ui/Paper';
import Drawer from 'material-ui/Drawer';
import Snackbar from 'material-ui/Snackbar';
import FontIcon from 'material-ui/FontIcon';
import FlatButton from 'material-ui/FlatButton';
import GroupAdd from 'material-ui/svg-icons/social/group-add';
import ExposurePlus1 from 'material-ui/svg-icons/image/exposure-plus-1';

import io from 'socket.io-client';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { replace } from 'react-router-redux';

import Footer from './Footer';
import Toolbar from './Toolbar';
import SideBar from './SideBar';
import CONFIG from '../../config';
import Feedback from '../Feedback';
import { moment } from '../Utils/Helper';
import NewActivity from '../Activity/NewActivity';
import * as actionCreators from '../../redux/actions/LayoutsAc';
import ReactMaterialUiNotifications from './ReactMaterialUiNotifications';
import { getMethod, parseJSON, postJsonMethod } from '../../redux/Helper';

// const SocketIo = io(CONFIG.ws, {transports: ['websocket']});
const SocketIo = io(CONFIG.devHost);

class Layouts extends Component {
  constructor(props) {
    super(props);
  }

  componentWillMount() {
    // 检查窗口
    if (window.innerWidth <= 768) {
      this.props.actions.windowWidthChange(true);
    }

  	// 获取user的基本信息，state中以user保存
  	this.props.actions.getData(this.props.userId, this.props.token);

    // 主题的更改
    this.props.actions.changeTheme(this.props.location.pathname);
  }

  componentDidMount() {
    // 监听window的宽度
    window.addEventListener('resize', this.onWindowResive);

    // 记录用户登录状态并且开始订阅通知
    let info = {userId: this.props.userId};
    this.socket = SocketIo;
    this.socket.emit('user login', info);

    // 触发初始化的通知数据事件
    let url = CONFIG.apiHost + '/api/home?token=' + this.props.token;
    fetch(url, getMethod);

    // 从web服务器获取到通知数据
    // 事件名[notification-userID]
    // push_notifications
    // json字符转换
    // 依据类型做不同操作
    let channel = `notification-${this.props.userId}`;
    this.socket.on(channel, (message) => {
      switch(message.type)
      {
        case 'push_notifications':
          this.props.actions.getInitNotification(message.notifications, message.messages);
          break;
        case 'join_succeed':
          this.showNotification(message);
          break;
        case 'add_friend_succeed':
          this.showAddFriendNotification(message);
          break;
        case 'receive_message':
          this.showMessage(message);
          break;
        case 'new_activity_apply':
          this.showApply(message);
          break;
      }
    });
  }

  componentWillReceiveProps (nextProps) {
    // 修改主题
    this.props.actions.changeTheme(nextProps.location.pathname);
  }

  componentWillUnmount() {
    window.removeEventListener('resize', this.onWindowResive);
  }

  /**
   * 窗口变化事件
   */
  onWindowResive = () => {
    if (window.innerWidth <= 768) {
      this.props.actions.windowWidthChange(true);
    } else {
      this.props.actions.windowWidthChange(false);
    }
  };

  /**
   * 活动通知
   */
  showNotification = (message) => {
    let detail = JSON.parse(message.detail);

    ReactMaterialUiNotifications.showNotification({
      refName: message.id,
      title: detail.title,
      additionalText: detail.sign,
      additionalLines: 2,
      icon: <FontIcon className="icon-insert_invitation" />,
      iconBadgeColor: this.props.color500,
      timestamp: moment(message.created_at).format('h:mm A'),
    });
    
    this.props.actions.addNotification('add_notifications');
  };

  /**
   * 加好友通知
   */
  showAddFriendNotification = (message) => {
    let detail = JSON.parse(message.detail);

    ReactMaterialUiNotifications.showNotification({
      refName: message.id,
      title: detail.user_name,
      additionalText: detail.sign,
      additionalLines: 2,
      icon: <GroupAdd />,
      personalised: true,
      avatar: detail.user_img,
      iconBadgeColor: this.props.color500,
      timestamp: moment(message.created_at).format('h:mm A')
    });

    this.props.actions.addNotification('add_notifications');
  };

  /**
   * 私信通知
   */
  showMessage = (message) => {
    ReactMaterialUiNotifications.showNotification({
      refName: `user${message.user_id}`,
      title: message.user_name,
      additionalText: message.detail,
      additionalLines: 2,
      icon: <FontIcon className="icon-message" />,
      personalised: true,
      avatar: message.user_img,
      iconBadgeColor: this.props.color500,
      timestamp: moment(message.created_at).format('h:mm A'),
      autoHide: 10000
    });

    this.props.actions.addNotification('add_messages');
  };

  /**
   * 申请通知
   */
  showApply = (message) => {
    let detail = JSON.parse(message.detail);

    let request = `?token=${this.props.token}`;
    let url = `${CONFIG.apiHost}/api/activity/join/${detail.activity_id}${request}`;
    let postData = {
      user_id: this.props.userId,
      companion_id: detail.user_id
    };

    ReactMaterialUiNotifications.showNotification({
      refName: message.id,
      title: detail.user_name,
      additionalText: detail.sign,
      additionalLines: 2,
      icon: <ExposurePlus1 />,
      personalised: true,
      avatar: detail.user_img,
      iconBadgeColor: this.props.color500,
      timestamp: moment(message.created_at).format('h:mm A'),
      overflowContent: <div>
        <FlatButton
          label="查看"
          icon={<FontIcon className="icon-open_in_new" />}
          onTouchTap={this.props.actions.pushTo.bind(this, `/activity/show/${detail.activity_id}`)}
        />
        <FlatButton
          label="同意"
          icon={<FontIcon className="icon-check" />}
          onTouchTap={() => {
            fetch(url, postJsonMethod(postData));
            this.refs.notifications.refs[message.id].onCloseNotification();
          }}
        />
      </div>,
    });

    this.props.actions.addNotification('add_notifications');
  };

  render() {
    const { 
      token, 
      userId, 
      userName, 
      userImg, 
      title, 
      color100, 
      color400, 
      color500,
      isChildrenPage,
      isSmallViewport,
    } = this.props;

    let url = this.props.location.pathname;

    // 子页面,设置初始值
    const children = React.Children.map(this.props.children,
      (child) => React.cloneElement(child, {
        url: url,
        token: token,
        userId: userId,
        userName: userName,
        userImg: userImg,
        color100: color100,
        color400: color400,
        color500: color500,
        socket: SocketIo,
        isSmallViewport: isSmallViewport,
        pushTo: this.props.actions.pushTo,
        backTo: this.props.actions.backTo,
        replaceTo: this.props.actions.replaceTo,
        handleOpen: this.props.actions.handleOpen,
        tokenExpired: this.props.actions.tokenExpired,
        handleOpenSnackbar: this.props.actions.handleOpenSnackbar,
      })
    );

    let panels = [
      <NewActivity
        key={0}
        token={token}
        userId={userId}
        userImg={userImg}
        color500={color500}
        isSmallViewport={isSmallViewport}
        open={this.props.openNewActivity}
        replaceTo={this.props.actions.replaceTo}
        handleClose={this.props.actions.handleClose}
        tokenExpired={this.props.actions.tokenExpired}
        handleOpenSnackbar={this.props.actions.handleOpenSnackbar}
      />,
      <Feedback
        key={1}
        token={token}
        userId={userId}
        isSmallViewport={isSmallViewport}
        open={this.props.openFeedback}
        handleOpen={this.props.actions.handleOpen}
        handleClose={this.props.actions.handleClose}
        tokenExpired={this.props.actions.tokenExpired}
        handleOpenSnackbar={this.props.actions.handleOpenSnackbar}
      />,
      <ReactMaterialUiNotifications
        ref='notifications'
        key={2}
        desktop={true}
        maxNotifications={6}
        transitionName={{
          leave: 'dummy',
          leaveActive: 'fadeOut',
          appear: 'dummy',
          appearActive: 'zoomInUp'
        }}
        rootStyle={styles.notification}
        transitionAppear={true}
        transitionLeave={true}
      />,
      <Snackbar
        key={3}
        open={this.props.openSnackbar}
        message={this.props.snackbarMessage}
        autoHideDuration={4000}
        onRequestClose={this.props.actions.handleCloseSnackbar}
      />,
    ];

  	return (
  	  <div style={styles.wrap}>
        <Toolbar 
          url={url}
          title={title}
          userId={userId}
          userImg={userImg}
          color100={color100}
          color400={color400}
          color500={color500}
          isChildrenPage={isChildrenPage}
          isSmallViewport={isSmallViewport}
          logout={this.props.actions.logout}
          pushTo={this.props.actions.pushTo}
          backTo={this.props.actions.backTo}
          replaceTo={this.props.actions.replaceTo}
          handleOpen={this.props.actions.handleOpen}
          handleTriggerDrawer={this.props.actions.handleTriggerDrawer}
          messages={this.props.messages}
          clearNotification={this.props.actions.clearNotification}
        />

        <Drawer
          zDepth={0}
          width={224}
          open={this.props.openDrawer}
          docked={!isSmallViewport}
          onRequestChange={this.props.actions.handleTriggerDrawer}
          containerStyle={{
            backgroundColor: '#F5F5F5',
            marginTop: isSmallViewport ? 0 : 88 + this.props.mainOffsetTop, 
          }}
        >
          <SideBar 
            url={url}
            color500={color500}
            userId={this.props.userId}
            pushTo={this.props.actions.pushTo}
            replaceTo={this.props.actions.replaceTo}
            handleOpen={this.props.actions.handleOpen}
            messages={this.props.messages}
            notifications={this.props.notifications}
            clearNotification={this.props.actions.clearNotification}
            isSmallViewport={isSmallViewport}
            handleTriggerDrawer={this.props.actions.handleTriggerDrawer}
          />
        </Drawer>

        <div
          className='main'
          style={{
            marginTop: isSmallViewport ? 80 + this.props.mainOffsetTop : 88 + this.props.mainOffsetTop,
            marginLeft: isSmallViewport ? 8 : 64 + this.props.mainOffsetLeft,
            marginRight: isSmallViewport ? 8 : 64,
          }}
        >
          {children}
        </div>
        {panels}
  	  </div>
  	);
  }
};

const styles = {
  wrap: {
    display: 'flex',
    minHeight: '100vh',
    flexDirection: 'row',
    backgroundColor: '#F5F5F5',
    overflowX: 'hidden'
  },
  box: {
    flex: 1
  },
  notification: {
    zIndex: 1000,
    bottom: 0,
    right: 0,
    padding: 8,
  }
};

const mapStateToProps = (state) => ({
  token: state.login.token,
  userId: state.login.userId,
  userImg: state.user.userImg,
  userName: state.user.userName,
  title: state.layouts.title,
  color100: state.layouts.color100,
  color400: state.layouts.color400,
  color500: state.layouts.color500,
  isChildrenPage: state.layouts.isChildrenPage,
  openDrawer: state.layouts.openDrawer,
  // 样式
  mainOffsetLeft: state.layouts.mainOffsetLeft,
  mainOffsetTop: state.layouts.mainOffsetTop,
  openTabs: state.layouts.openTabs,
  openNewActivity: state.layouts.openNewActivity,
  openFeedback: state.layouts.openFeedback,
  openSnackbar: state.layouts.openSnackbar,
  snackbarMessage: state.layouts.snackbarMessage,
  isSmallViewport: state.layouts.isSmallViewport,
  // 通知
  messages: state.notification.messages,
  notifications: state.notification.notifications,
});

const mapDispatchToProps = (dispatch) => ({
  actions: bindActionCreators(actionCreators, dispatch)
});

export default connect(mapStateToProps, mapDispatchToProps)(Layouts);
